package yt.demo.appcommontools.utils.files.storage;

import cn.hutool.core.codec.Base64;
import lombok.Data;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.beans.factory.annotation.Value;
import yt.demo.appcommonbean.exception.LogicException;
import yt.demo.appcommontools.utils.FileUtils;
import yt.demo.appcommontools.utils.RequestUtils;
import yt.demo.appcommontools.utils.dto.FileInfoDTO;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

@Data
@Service
public class LocalStorageService implements FileStorageService {

    @Value("${file.storage.local.uploadDir}")
    private String uploadDir;

    @Value("${file.storage.local.domainName}")
    private String domainName;

    @Override
    public FileInfoDTO upload(MultipartFile file) {
        try {
            String filePath = "/" + FileUtils.getFilePath() + "/";
            String path = uploadDir + filePath;
            File directory = new File(path);
            if (!directory.exists()) {
                directory.mkdirs(); // 创建目录
            }

            String originalFileName = file.getOriginalFilename();
            String fileExtension = FileUtils.getFileExtension(originalFileName);
            String fileName = System.currentTimeMillis() + "." + fileExtension;
            path = FileUtils.removeLeadingDot(path) + fileName;
            String resourceType = file.getContentType();

            File targetFile = new File(directory, fileName);
            // 写入文件
            try (FileOutputStream fos = new FileOutputStream(targetFile)) {
                fos.write(file.getBytes());
            }
            FileInfoDTO fileInfo = new FileInfoDTO();
            fileInfo.setOriginName(originalFileName);
            fileInfo.setObjectName(fileName);
            fileInfo.setMimeType(resourceType);
            fileInfo.setStoragePath(FileUtils.getFilePath());
            fileInfo.setSuffix(fileExtension);
            fileInfo.setSizeByte(file.getSize());
            fileInfo.setFileHash(FileUtils.calculateFileHash(originalFileName));
            fileInfo.setSizeInfo(FileUtils.formatFileSize(file.getSize()));
            fileInfo.setUrl(path);
            return fileInfo;
        } catch (IOException e) {
            throw new LogicException("文件上传失败");
        }
    }

    @Override
    public FileInfoDTO uploadBase64(String base64Data) {
        try {
            String filePath = "/" + FileUtils.getFilePath() + "/";
            String path = uploadDir + filePath;
            String mimeType = FileUtils.getBase64MimeType(base64Data);
            String fileExtension = FileUtils.getFileExtensionFromMimeType(mimeType);

            // 去掉数据头部分
            String base64Content = base64Data.split(",")[1];

            // 解码 Base64 数据
            byte[] decodedBytes = Base64.decode(base64Content);

            File directory = new File(path);
            if (!directory.exists()) {
                directory.mkdirs(); // 创建目录
            }

            String fileName = System.currentTimeMillis() + "." + fileExtension;
            File targetFile = new File(directory, fileName);

            // 写入解码后的字节数组到文件
            try (FileOutputStream fos = new FileOutputStream(targetFile)) {
                fos.write(decodedBytes);
            }

            String fileHash = FileUtils.calculateFileHash(base64Content);
//            // 文件大小
            long fileSize = decodedBytes.length; // 使用解码后的字节数组长度
            path = FileUtils.removeLeadingDot(path) + fileName;
            // 创建并返回 FileInfoDTO 对象
            FileInfoDTO fileInfo = new FileInfoDTO();
            fileInfo.setOriginName("");
            fileInfo.setObjectName(fileName);
            fileInfo.setMimeType(mimeType);
            fileInfo.setStoragePath(FileUtils.getFilePath());
            fileInfo.setSuffix(fileExtension);
            fileInfo.setSizeByte(fileSize);
            fileInfo.setFileHash(fileHash);
            fileInfo.setSizeInfo(FileUtils.formatFileSize(fileSize));
            fileInfo.setUrl(path);
            return fileInfo;
        } catch (IllegalArgumentException e) {
            throw new LogicException("无效的 Base64 数据");
        } catch (IOException e) {
            throw new LogicException("Base64 文件上传失败");
        }
    }

    @Override
    public String getDomainName() {
        if (domainName.isEmpty()) {
            return RequestUtils.getCurrentDomain();
        }
        return domainName;
    }

    @Override
    public boolean delete(String fileUrl) {
        return false;
    }
}
